/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.das.commonmodel.json.object;

import com.fasterxml.jackson.core.JsonGenerator;
import com.inspur.edp.cef.designtime.api.IGspCommonDataType;
import com.inspur.edp.cef.designtime.api.json.CefNames;
import com.inspur.edp.cef.designtime.api.json.SerializerUtils;
import com.inspur.edp.cef.designtime.api.json.element.CefFieldSerializer;
import com.inspur.edp.cef.designtime.api.json.object.GspCommonDataTypeSerializer;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.das.commonmodel.entity.GspCommonObject;
import com.inspur.edp.das.commonmodel.entity.object.ConstraintType;
import com.inspur.edp.das.commonmodel.entity.object.GspCommonObjectType;
import com.inspur.edp.das.commonmodel.entity.object.GspUniqueConstraint;
import com.inspur.edp.das.commonmodel.json.CommonModelNames;
import com.inspur.edp.das.commonmodel.json.element.CmElementSerializer;
import lombok.var;

/**
 * The Json Serializer Of Common Model Object
 *
 * @ClassName: CmObjectSerializer
 * @Author: Benjamin Gong
 * @Date: 2021/1/11 17:13
 * @Version: V1.0
 */
public abstract class CmObjectSerializer extends GspCommonDataTypeSerializer {

    private final String ParentObjectID = "ParentObjectID";
    public CmObjectSerializer(){}
    public CmObjectSerializer(boolean full){
        super(full);
        isFull = full;
    }
    //region BaseProp
    @Override
    protected void writeExtendCdtBaseProperty(IGspCommonDataType dataType, JsonGenerator writer) {
        GspCommonObject bizObject = (GspCommonObject)dataType;
        writeContainChildObjects(writer, bizObject);
        if(isFull||(bizObject.getRepositoryComps()!=null&&bizObject.getRepositoryComps().size()>0)){
            SerializerUtils.writePropertyName(writer,CommonModelNames.RepositoryComps);
            SerializerUtils.writePropertyValue_Object(writer,bizObject.getRepositoryComps());}
        if(isFull||(bizObject.getRefObjectName()!=null&&!"".equals(bizObject.getRefObjectName()))){
            SerializerUtils.writePropertyValue(writer, CommonModelNames.RefObjectName, bizObject.getRefObjectName());}
        if(isFull||(bizObject.getObjectType()!= GspCommonObjectType.MainObject)){
            SerializerUtils.writePropertyValue(writer, CommonModelNames.ObjectType, bizObject.getObjectType().getValue());}
        //扩展对象属性
        writeExtendObjectBaseProperty(writer, bizObject);
    }

    private void writeContainChildObjects(JsonGenerator writer, GspCommonObject bizObject)
    {
        if (isFull||(bizObject.getContainChildObjects().size() > 0&&bizObject.getContainChildObjects()!=null)) {
            SerializerUtils.writePropertyName(writer, CommonModelNames.ContainChildObjects);
            //[
            SerializerUtils.WriteStartArray(writer);
            if (bizObject.getContainChildObjects().size() > 0) {
            for(var childObject :bizObject.getContainChildObjects()){
                serialize(childObject, writer, null);
            }
            }
            //]
            SerializerUtils.WriteEndArray(writer);
        }

    }

    //endregion

    //region SelfProp
    @Override
    protected final void writeExtendCdtSelfProperty(IGspCommonDataType dataType, JsonGenerator writer)
    {
        GspCommonObject bizObject = (GspCommonObject)dataType;

//        SerializerUtils.writePropertyValue(writer, CommonModelNames.LogicDelete, bizObject.LogicDelete);
        SerializerUtils.writePropertyValue(writer, CommonModelNames.ColumnGenerateID, bizObject.getColumnGenerateID()); //主键 不变
        writeContainConstraints(writer, bizObject);
        if(isFull||(bizObject.getOrderbyCondition()!=null&&!"".equals(bizObject.getOrderbyCondition()))){
            SerializerUtils.writePropertyValue(writer, CommonModelNames.OrderbyCondition, bizObject.getOrderbyCondition());}
        if(isFull||(bizObject.getFilterCondition()!=null&&!"".equals(bizObject.getFilterCondition()))){
            SerializerUtils.writePropertyValue(writer, CommonModelNames.FilterCondition, bizObject.getFilterCondition());}
//        SerializerUtils.writePropertyValue(writer, CommonModelNames.ModifiedDateElementID, bizObject.ModifiedDateElementID);
//        SerializerUtils.writePropertyValue(writer, CommonModelNames.CreatorElementID, bizObject.CreatorElementID);
//        SerializerUtils.writePropertyValue(writer, CommonModelNames.CreatedDateElementID, bizObject.CreatedDateElementID);
//        SerializerUtils.writePropertyValue(writer, CommonModelNames.ModifierElementID, bizObject.ModifierElementID);
//
//        SerializerUtils.writePropertyValue(writer, CommonModelNames.RecordDelData, bizObject.RecordDelData);
        if(isFull||bizObject.getIsReadOnly()){
            SerializerUtils.writePropertyValue(writer, CommonModelNames.IsReadOnly, bizObject.getIsReadOnly());}
        if(isFull||bizObject.getIsVirtual()){
            SerializerUtils.writePropertyValue(writer, CommonModelNames.IsVirtual, bizObject.getIsVirtual());}
        if(isFull||(bizObject.getBelongModelID()!=null&&!"".equals(bizObject.getBelongModelID()))){
            SerializerUtils.writePropertyValue(writer, CommonModelNames.BelongModelID, bizObject.getBelongModelID());}
        //writeGspHirarcheInfo(writer, bizObject);
        writeGspAssociationKeyCollection(writer, bizObject);
//        if(bizObject.getStateElementID()!=null&&!"".equals(bizObject.getStateElementID())){
//        SerializerUtils.writePropertyValue(writer, CommonModelNames.StateElementID, bizObject.getStateElementID());}
        //前端使用ParentObjectId
        if (bizObject.getParentObject() != null)//不要了
        {
            SerializerUtils.writePropertyValue(writer, ParentObjectID, bizObject.getParentObject().getID());
        }

    //扩展对象属性
        writeExtendObjectSelfProperty(writer, bizObject);
    }

    private void writeContainConstraints(JsonGenerator writer, GspCommonObject bizObject)
    {
        if(!isFull&&(bizObject.getContainConstraints()==null||bizObject.getContainConstraints().size()==0)){
            return;
        }
        //ContainConstraints：
        SerializerUtils.writePropertyName(writer, CommonModelNames.ContainConstraints);
        //[
        SerializerUtils.WriteStartArray(writer);
        if (bizObject.getContainConstraints() != null && bizObject.getContainConstraints().size() > 0)
        {
            for (GspUniqueConstraint item : bizObject.getContainConstraints())
            {
                SerializerUtils.writeStartObject(writer);
                SerializerUtils.writePropertyValue(writer, CommonModelNames.ID, item.getId());
                SerializerUtils.writePropertyValue(writer, CommonModelNames.Code, item.getCode());
                SerializerUtils.writePropertyValue(writer, CommonModelNames.Name, item.getName());
                if(isFull||item.getType()!= ConstraintType.Unique)
                    SerializerUtils.writePropertyValue(writer, CommonModelNames.Type, item.getType());
                if(isFull||(item.getConstraintMessage()!=null&&!"".equals(item.getConstraintMessage())))
                    SerializerUtils.writePropertyValue(writer, CommonModelNames.ConstraintMessage, item.getConstraintMessage());
                SerializerUtils.writePropertyValue(writer, CefNames.I18nResourceInfoPrefix, item.getI18nResourceInfoPrefix());
                //cef上有关于字段的处理 ElementList
                writeElementList(writer, item, bizObject);
                SerializerUtils.writeEndObject(writer);
            }
        }
        //]
        SerializerUtils.WriteEndArray(writer);
    }

    private void writeElementList(JsonGenerator writer, GspUniqueConstraint item, GspCommonObject bizObject)
    {
        //ElementList
        var collection = item.getElementList();
        if (isFull||(collection!=null&&collection.size()>0))
        {
            SerializerUtils.writePropertyName(writer, CommonModelNames.ElementList);
            //[
            SerializerUtils.WriteStartArray(writer);
            if (collection.size() > 0)
            {
            for (var elementId :collection){
                var element = bizObject.findElement(elementId);
                getFieldSerializer().serialize(element, writer,null);
            }
            }
            //]
            SerializerUtils.WriteEndArray(writer);
        }
    }
    private void writeGspHirarcheInfo(JsonGenerator writer, GspCommonObject bizObject) {
//        SerializerUtils.writePropertyName(writer, CommonModelNames.HirarchyInfo);
//        SerializerUtils.writeStartObject(writer);
//        GSPHirarchyInfo hirarchyInfo = bizObject.HirarchyInfo;
//        if (hirarchyInfo != null)
//        {
//            WriteElementID(writer, CommonModelNames.ISDETAILELEMENT, hirarchyInfo.IsDetailElement);
//            WriteElementID(writer, CommonModelNames.LayerElement, hirarchyInfo.LayerElement);
//            WriteElementID(writer, CommonModelNames.ParentElement, hirarchyInfo.ParentElement);
//            WriteElementID(writer, CommonModelNames.ParentRefElement, hirarchyInfo.ParentRefElement);
//            WriteElementID(writer, CommonModelNames.PathElement, hirarchyInfo.PathElement);
//            SerializerUtils.WritePropertyValue(writer, CommonModelNames.PathGenerateType, hirarchyInfo.PathGenerateType);
//            SerializerUtils.WritePropertyValue(writer, CommonModelNames.PathLength, hirarchyInfo.PathLength);
//        }
//        SerializerUtils.writeEndObject(writer);
    }

    private void writeGspAssociationKeyCollection(JsonGenerator writer, GspCommonObject bizObject) {

        if (isFull||(bizObject.getKeys().size() > 0&&bizObject.getKeys()!=null))
        {
            //外键集合
            SerializerUtils.writePropertyName(writer, CommonModelNames.Keys);
            //[
            SerializerUtils.WriteStartArray(writer);
            if (bizObject.getKeys().size() > 0)
            {
            for(var item : bizObject.getKeys())
            {
                SerializerUtils.writePropertyValue_Object(writer, item);
            }
            }
            //]
            SerializerUtils.WriteEndArray(writer);
        }
    }

    //endregion

    @Override
    protected final CefFieldSerializer getFieldSerializer(){
        return gspCommonDataTypeSerializer();
    }

    protected  abstract CmElementSerializer gspCommonDataTypeSerializer();

    protected abstract void writeExtendObjectBaseProperty(JsonGenerator writer, IGspCommonObject bizObject);

    protected abstract void writeExtendObjectSelfProperty(JsonGenerator writer, IGspCommonObject bizObject);

}


